package concurrent.chapter7;

public class ImmutablePerformance {
    public static void main(String[] args) throws InterruptedException {
        long startTimestamp = System.currentTimeMillis();
        SyncObj obj = new SyncObj();
        obj.setName("Alex");
        //ImmutableObj obj = new ImmutableObj("Alex");
        Thread t1 = new Thread() {
            @Override
            public void run() {
                for (long i = 0L; i < 1000000; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + obj.toString());
                }
            }
        };
        t1.start();

        Thread t2 = new Thread() {
            @Override
            public void run() {
                for (long i = 0L; i < 1000000; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + obj.toString());
                }
            }
        };
        t2.start();
        t1.join();
        t2.join();

        long endTimestamp = System.currentTimeMillis();
        System.out.println("Elapsed time " + (endTimestamp - startTimestamp));
        //synchronized: Elapsed time 7349
        //ImmutableObj: Elapsed time 7326
    }
}

final class ImmutableObj {
    private final String name;

    public ImmutableObj(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "[" + name + ']';
    }
}

class SyncObj {
    private String name;

    public synchronized void setName(String name) {
        this.name = name;
    }

    @Override
    public synchronized String toString() {
        return "[" + name + ']';
    }
}
